
from traceback import print_exc

OPERATORS = ['<', '>', ]

class Operand:
	TYPES = ['alwaystrue', 'worldattribute', 'literal',]
	
	def __init__(self, **kw):
		self.type = 'alwaystrue'
		self.value = 'alwaystrue'
		self.__dict__.update(kw)
	
	def process(self, world):
		if self.type == 'worldattribute':
			return world[self.value]
		elif self.type == 'literal':
			return self.value
		raise Exception(' %s type not implemented' % (self.type,))
	
	def copy(self):
		return Operand(type=self.type, value=self.value)

class Condition:
	""" Represents condition
	"""
	def __init__(self, **kw):
		self._first = Operand()
		self._operator = '<'
		self._second = Operand()
		self.__dict__.update(kw)
	
	def evaluate(self, world):
		try:
			if self._first.type == 'alwaystrue' or self._second.type == 'alwaystrue':
				return True
			
			first = self._first.process(world)
			second = self._second.process(world)
			if self.operator == '<':
				return first < second
			else:
				return first > second
		except:
			print_exc()
			print '[condition] f:%s %s s:%s, world do not have those attributes !' % (self._first, self._operator, self._second, )
			return False
	
	def copy(self):
		return Condition(_first=self._first.copy(), _operator=self._operator,_second=self._second.copy())
	
	def __str__(self):
		return '%s %s %s' % (self._first.value, self._operator, self._second.value, )

class Rank:
	""" map priority points to condition validated ..
	"""
	def __init__(self, condition, priority_points):
		self.condition = condition
		self.rank = priority_points
	
	def copy(self):
		return Rank(self.condition.copy(), self.rank)
	
	def __str__(self):
		""" displayed within gui list object """
		return 'priority gain: %s | %s' % (self.rank, self.condition, )

class CompoundCondition:
	""" groups priority entries
	"""
	def __init__(self, **kw):
		self._statements = []	## list of Rank() s
		self.__dict__.update( kw )
	
	def evaluate(self, world):
		rank = 0
		for statement in self._statements:
			if statement.condition.evaluate( world ):
				rank += statement.rank
		return rank
	
	def copy(self):
		ret = []
		for s in self._statements:
			ret.append( s.copy() )
		return CompoundCondition(_statements=ret)
	
	## planer interface ...
	
	def __str__(self):
		ret = 'compound condition:\n'
		for x in self._statements:
			ret += str(x) + '\n'
		return ret
	
	def enumerate(self):
		return self._statements[:]
	
	def add_statement(self, condition, rank):
		ret = Rank(condition, rank)
		self._statements.append( ret )
		return ret
		
	def edit_statement(self, index, condition, rank):
		if index < 0 or index >= len(self._statements):
			raise Exception('index %s out of bounds' % (index, ))
		self._statements[index] = Rank(condition, rank)
	
	def remove_statement(self, index):
		if index < 0 or index >= len(self._statements):
			raise Exception('index %s out of bounds' % (index, ))
		self._statements.pop(index)
	
	def get_statement(self, index):
		return self._statements[index]





